using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GameAOT;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public enum SceneBlockLoadState
    {
        Init = 0,
        Loading,
        LoadComplete,
    }

    public class SceneBlock : IReusableClass, IDisposable
    {
        public int id { private set; get; }
        public int x { private set; get; }
        public int y { private set; get; }

        // 分块场景的配置
        private SceneBlockConfig _sceneBlockConfig;

        public GameObject gameObject { private set; get; }

        public ResLoader resLoader { private set; get; }

        public string assetPath { private set; get; }

        public float existTime { private set; get; }

        /// <summary>
        /// 加载完毕，包括失败
        /// </summary>
        public SceneBlockLoadState loadState { private set; get; } = SceneBlockLoadState.Init;

        private uint _waiterTimer = 0;

        public void InitSceneBlock(int id, int x, int y, SceneBlockConfig sceneBlockConfig)
        {
            this.id = id;
            this.x = x;
            this.y = y;
            this._sceneBlockConfig = sceneBlockConfig;
            resLoader = ResLoader.Create();
            assetPath = GetSceneBlockPrefabPath();
        }

        /// <summary>
        ///  地图分块的目录
        /// </summary>
        /// <returns></returns>
        private string GetSceneBlockPrefabPath()
        {
            return PathConstant.GetSceneBlockPrefabPath(_sceneBlockConfig.sceneName, x + 1, y + 1);
        }

        /// <summary>
        /// 检测是否有分块资源
        /// </summary>
        /// <returns></returns>
        public bool CheckHasBlockResource()
        {
            return ManagerCenter.Res.ContainsAsset(assetPath);
        }

        /// <summary>
        /// 加载等待完成
        /// </summary>
        /// <returns></returns>
        public async UniTask LoadSceneBlockAsync()
        {
            loadState = SceneBlockLoadState.Loading;

            existTime = Time.realtimeSinceStartup + SceneBlockUtility.BlockExistMinTime + UnityEngine.Random.Range(0, 1);

            var prefab = await resLoader.LoadABAssetAwait<GameObject>(assetPath);
            // 等待一帧再实例化，防止卡顿
            _waiterTimer = TimerManager.Instance.StartOneTimer(1, TimerType.Frame);
            await _waiterTimer.AwaitTimer();
            _waiterTimer = 0;
            // 实例化BlockPrefab
            InitSceneBlockObject(prefab);

            loadState = SceneBlockLoadState.LoadComplete;
        }

        private void InitSceneBlockObject(GameObject prefab)
        {
            if (prefab == null)
            {
                return;
            }
            // 实例化到一个父物体上
            gameObject = prefab.Instantiate(_sceneBlockConfig.sceneRoot);

            // 设置位置，之后还可以添加偏移。
            // gameObject.transform.SetPositionAndRotation(new Vector3((x + 0.5f) * SceneBlockUtility.BlockSize, 0, (y + 0.5f) * SceneBlockUtility.BlockSize), Quaternion.identity);

        }

        public void Dispose()
        {
            id = 0;
            x = 0;
            y = 0;
            existTime = 0;
            if (resLoader != null)
            {
                resLoader.Put2Pool();
                resLoader = null;
            }
            if (gameObject != null)
            {
                UnityEngine.Object.Destroy(gameObject);
                gameObject = null;
            }
            if (_waiterTimer > 0)
            {
                _waiterTimer.StopTimer();
                _waiterTimer = 0;
            }
            _sceneBlockConfig = null;
            assetPath = null;
            loadState = SceneBlockLoadState.Init;
        }

        public uint MaxStore => 20;

        public void OnReset()
        {
            Dispose();
        }
    }
}
